package com.language.points.multi.thread.zhishu;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 查找多少以内的质数-多线程方法
 * @author yll
 * @version 1.0.0
 * @date 2024/04/14 14：55
 * @desc 多线程方法
 * */
public class FindZhiShuThread extends BaseFindZhiShu {

    Integer corePoolSize = 0;
    final Integer minCorePoolSize = 2;
    final Integer maxCorePoolSize = 20;
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(minCorePoolSize, maxCorePoolSize, 0, TimeUnit.SECONDS,new ArrayBlockingQueue(2));

    long startTime = 0L;
    long endTime = 0L;


    public static void main(String[] args) {
        FindZhiShuThread findZhiShu = new FindZhiShuThread();
        Scanner scanner = new Scanner(System.in);
        Integer startNum, endNum;
        do {
            System.out.print("请输入查找范围的起始值（大于1）:");
            startNum = scanner.nextInt();
            System.out.print("请输入查找范围的结束值（大于1）:");
            endNum = scanner.nextInt();
            findZhiShu.find(startNum, endNum);
            findZhiShu.showZhiShu();
            System.out.print("是否继续？（继续/1；结束/0）:");
            System.out.println("");
            startNum = scanner.nextInt();
        }while (startNum == 1);
    }

    public void showZhiShu()  {
        do {
        }while (corePoolSize != threadPoolExecutor.getCompletedTaskCount());
//        if(threadList != null && threadList.size() > 0) {
//            do {
//                boolean is_next = true;
//                for (Thread thread : threadList) {
//                    if (!thread.getState().equals(Thread.State.TERMINATED)) {
//                        is_next = false;
//                        break;
//                    }
//                }
//                if (is_next) {
//                    break;
//                }
//            } while (true);
//            System.out.println("***********");
//            for (Thread thread : threadList) {
////            System.out.println(thread.getState());
//                thread = null;
//            }
//            threadList.clear();
//        }


        endTime = System.nanoTime();
        long executionTime = endTime - startTime;
        System.out.println("执行时间: " + executionTime / 1000  + " 微秒");

        super.showZhiShu();
    }

    public void checkZhiShuThread(Integer id, List<Integer> numList){
//        Thread thread = new Thread() {
//            @Override
//            public void run() {
//                try{
//                    List<Integer> tempList = new ArrayList<>();
//                    for (Integer num : numList){
//                        if(checkZhiShu(num)){
//                            tempList.add(num);
//                        }
//                    }
//                    addZhiShuList(tempList);
//                }catch (Exception e){
//                    e.printStackTrace();
//                }finally {
//
//                }
//            }
//        };
//        thread.start();
//        threadList.add(thread);
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                List<Integer> tempList = new ArrayList<>();
                for (Integer num : numList){
                    if(checkZhiShu(num)){
                        tempList.add(num);
                        zhishuList.add(num);
                    }
                }
//                addZhiShuList(tempList);
            }
        });
        corePoolSize++;
    }

    public void find(Integer startNum, Integer endNum) {

        if(startNum > endNum){
            return;
        }

        Integer num = endNum - startNum + 1;
        if(num < 500){
            startTime = System.nanoTime();
            findZhiShu(startNum, endNum);
        }else{
            int threadNum = 2;

            if(num > 50000){
                threadNum = 20;
            }else if(num > 30000){
                threadNum = 15;
            }else if(num > 10000){
                threadNum = 10;
            }else if(num > 5000){
                threadNum = 5;
            }else if(num > 3000){
                threadNum = 3;
            }else {
                threadNum = 2;
            }
            Map<Integer, List> threadMap = new HashMap<>();
            for (int i = 1; i <= threadNum; i++){
                List<Integer> numList = new ArrayList<>();
                threadMap.put(i, numList);
            }
            for (int j = startNum; j <= endNum;){
                for (int i = 1; i <= threadNum && j <= endNum; i++){
                    threadMap.get(i).add(j++);
                }
            }
            startTime = System.nanoTime();
            for (int i = 1; i <= threadNum; i++){
                checkZhiShuThread(i, threadMap.get(i));
            }
        }
    }
}
